<template>
	<!-- Header: Display Name and IP -->
	<div class="info-header">
	  <span class="name">{{ longname }}</span>
	  <span class="ip">{{ ip }}</span>
	  <!-- <el-button @click="change" style="padding: 0 20px">change</el-button> -->
	</div>
	<div style="height: 100%">
	  <div class="container">
		<div class="left-side" id="network-details" style="width: 100%; height: 100%"></div>
		<div class="right-side">
		  <div class="clean">
			<div class="load-chart" id="load-chart" style="height: 100%"></div>
		  </div>
		  <div class="graph-modal">
			<div v-if="selectedGraph === 'input'">
			  <Input :data="ioData" ref="inputChart" />
			</div>
			<div v-if="selectedGraph === 'output'">
			  <Output :data="ioData" ref="outputChart" />
			</div>
			<div v-if="selectedGraph === 'cpu'">
			  <CPU :data="cpuData" ref="cpuChart" />
			</div>
			<div v-if="selectedGraph === 'gpu'">
			  <Gpu :data="gpuData" ref="gpuChart" />
			</div>
			<div v-if="selectedGraph === 'gpurate'">
			  <GpuRate :data="gpuRate" ref="gpuRateChart" />
			</div>
			<div v-if="selectedGraph === 'memory'">
			  <Memory :data="memData" ref="memoryChart" />
			</div>
			<div v-if="selectedGraph === 'diskread'">
			  <DiskRead :data="diskRead" ref="diskReadChart" />
			</div>
			<div v-if="selectedGraph === 'diskwrite'">
			  <DiskWrite :data="diskWrite" ref="diskWriteChart" />
			</div>
		  </div>
		</div>
	  </div>
	</div>
  </template>
  
  <script>
  import CPU from "./CPUGraph.vue";
  import Memory from "./MemoryGraph.vue";
  import Gpu from "./GpuGraph.vue";
  import Input from "./InputGraph.vue";
  import Output from "./OutputGraph.vue";
  import GpuRate from "./GpuRateGraph.vue";
  import DiskRead from "./DiskReadGraph.vue";
  import DiskWrite from "./DiskWriteGraph.vue";
  import axios from "axios";
  import * as echarts from "echarts";
  import { loadConfig } from "@/utils/config";
  
  export default {
	components: {
	  CPU,
	  Memory,
	  Gpu,
	  Input,
	  Output,
	  GpuRate,
	  DiskRead,
	  DiskWrite,
	},
	props: {
	  name: {
		type: String,
		default: "",
	  },
	},
	data() {
	  return {
		data: [],
		cpuData: [],
		memData: [],
		gpuData: [],
		gpuRate: [],
		diskRead: [],
		diskWrite: [],
		ioData: [],
		jsonData: {},
		filteredInstances: {},
		ip: "",
		longname: "",
		intervalId: null,
		showGraphModal: true,
		selectedGraph: "cpu",
		currentState: 0,
		ws: null,
		message: "",
		loadChart: null,
		currentLoad: 50, // 当前负载值
		maxLoad: 130, // 最大负载值
		resourceData: [
		  { value: 80, name: "通" },
		  { value: 60, name: "算" },
		  { value: 30, name: "存" },
		],
		option: [
		  {
			tooltip: {},
			series: [
			  {
				type: "graph",
				layout: "none",
				data: [
				  { name: "通", x: 200, y: 100, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
				  { name: "算", x: 100, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
				  { name: "存", x: 300, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
				  { name: "Input", x: 150, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "Output", x: 250, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "CPU", x: 0, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "GPU", x: 0, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "GPU %", x: 80, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "Memory", x: 400, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "Disk Wr", x: 400, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				  { name: "Disk Rd", x: 320, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
				],
				links: [
				  { source: "通", target: "算", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "算", target: "存", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "存", target: "通", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "通", target: "Input", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "通", target: "Output", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "算", target: "CPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "算", target: "GPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "算", target: "GPU %", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "存", target: "Memory", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "存", target: "Disk Wr", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				  { source: "存", target: "Disk Rd", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				], // 初始化为空
				label: {
				  show: true,
				  position: "inside",
				  formatter: "{b}",
				  color: "black",
				  fontSize: 22,
				},
				lineStyle: {
				  curveness: 0,
				  width: 2,
				  color: "white",
				  opacity: 1,
				},
			  },
			],
		  },
		],
	  };
	},
	methods: {
	  connectWebSocket() {
		// 创建 WebSocket 连接
		this.ws = new WebSocket("ws://10.112.51.79:38414/ws");
  
		// 监听消息
		this.ws.onmessage = (event) => {
		  console.log("Received:", event.data);
		  this.message = event.data; // 显示接收到的消息
		  if (this.message.includes("U 1")) {
			this.change(1);
		  } else if (this.message.includes("H 1 2")) {
			this.change(0);
		  }
		};
  
		// 监听 WebSocket 连接关闭
		this.ws.onclose = () => {
		  console.log("WebSocket connection closed");
		};
  
		// 监听 WebSocket 错误
		this.ws.onerror = (error) => {
		  console.error("WebSocket error:", error);
		};
	  },
	  sendMessage() {
		if (this.ws && this.ws.readyState === WebSocket.OPEN) {
		  // 发送消息
		  this.ws.send("Hello from Vue!");
		}
	  },
	  initLoadChart() {
		const container = document.getElementById("load-chart");
		if (container) {
		  this.loadChart = echarts.init(container);
		  this.updateLoadChart();
		}
	  },
  
	  updateLoadChart() {
		if (!this.loadChart) return;
  
		// 计算各资源占比
		const tong = this.resourceData.find((d) => d.name === "通").value;
		const suan = this.resourceData.find((d) => d.name === "算").value;
		const cun = this.resourceData.find((d) => d.name === "存").value;
  
		const option = {
		  tooltip: {
			trigger: "item",
			formatter: "{a} <br/>{b}: {d}%",
		  },
		  legend: {
			show: true,
			orient: "horizontal",
			bottom: 0,
			left: "center",
			data: ["负载", "通", "算", "存"],
			textStyle: {
			  color: "#fff",
			  fontSize: 16,
			},
			itemWidth: 30,
			itemHeight: 10,
			itemGap: 20,
		  },
		  series: [
			{
			  name: "负载占比",
			  type: "pie",
			  radius: ["0%", "50%"],
			  center: ["50%", "50%"],
			  avoidLabelOverlap: true,
			  itemStyle: {
				borderRadius: 10,
				borderColor: "#fff",
				borderWidth: 2,
			  },
			  label: {
				show: true,
				position: "center",
				formatter: `${((this.currentLoad / this.maxLoad) * 100).toFixed(2)}%`,
				fontSize: 30,
				fontWeight: "bold",
				color: "#fff",
			  },
			  labelLine: {
				show: false,
			  },
			  data: [
				{
				  value: this.currentLoad,
				  name: "负载",
				  itemStyle: { color: this.currentLoad < 50 ? "#91cc75" : this.currentLoad < 90 ? "#fac858" : "#e34a18" },
				},
				{
				  value: this.maxLoad - this.currentLoad,
				  name: "剩余",
				  itemStyle: { color: "transparent" },
				},
			  ],
			},
			{
			  name: "资源占比",
			  type: "pie",
			  radius: ["60%", "80%"],
			  center: ["50%", "50%"],
			  avoidLabelOverlap: true,
			  itemStyle: {
				borderColor: "#fff",
				borderWidth: 2,
			  },
			  label: {
				show: true,
				formatter: (params) => {
				  if (!params.name.includes("剩余")) {
					return `${params.name}\n${params.value}%`;
				  } else {
					return "";
				  }
				},
				fontSize: 16,
				fontWeight: "bold",
				color: "#fff",
			  },
			  labelLine: {
				smooth: true,
				length: 10,
				length2: 10,
			  },
			  data: [
				{ value: tong, name: "通", itemStyle: { color: tong < 33 ? "#91cc75" : tong < 66 ? "#fac858" : "#e34a18" } },
				{ value: 100 - tong, name: "通-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
				{ value: suan, name: "算", itemStyle: { color: suan < 33 ? "#91cc75" : suan < 66 ? "#fac858" : "#e34a18" } },
				{ value: 100 - suan, name: "算-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
				{ value: cun, name: "存", itemStyle: { color: cun < 33 ? "#91cc75" : cun < 66 ? "#fac858" : "#e34a18" } },
				{ value: 100 - cun, name: "存-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
			  ],
			},
		  ],
		};
  
		this.loadChart.setOption(option);
	  },
  
	  async fetchData() {
		try {
		  let that = this;
		  const config = await loadConfig();
		  const apiUrl = config.apiUrl;
		  await axios.get(`${apiUrl}/get_nf_data?nf=${this.name}`).then(function (res) {
			that.data = res.data;
		  });
		  await axios.get(`${apiUrl}/get_path`).then(function (res) {
			if (that.name === "upf-0") {
			  that.currentLoad = res.data[0].upf0_load;
			} else if (that.name === "upf-1") {
			  that.currentLoad = res.data[0].upf1_load;
			} else if (that.name === "upf-2") {
			  that.currentLoad = res.data[0].upf2_load;
			} else if (that.name === "upf-3") {
			  that.currentLoad = res.data[0].upf3_load;
			}
			that.currentLoad = that.currentLoad.toFixed(2);
			that.updateLoadChart();
		  });
		  this.cpuData = this.data.phy_cpu_list;
		  this.memData = this.data.phy_mem_list;
		  this.gpuData = this.data.gpu_list;
		  this.ioData = this.data.net_io_list;
		  this.gpuRate = this.data.gpu_rate;
		  this.diskRead = this.data.disk_read;
		  this.diskWrite = this.data.disk_write;
		  this.ip = this.data.ip;
		  this.longname = this.data.name;
		  // console.log(this.gpuRate);
		  if (this.showGraphModal) this.updateChartData();
		} catch (error) {
		  console.error("Failed to fetch data:", error);
		}
	  },
	  initChart() {
		const container = document.getElementById("network-details");
		if (container) {
		  this.myChart = echarts.init(container);
		  this.myChart.setOption(this.option[0]);
		}
		this.refreshCharts();
		// 添加点击事件
		this.myChart.on("click", this.handleNodeClick);
	  },
	  destroyChart() {
		if (this.myChart) {
		  this.myChart.dispose(); // 销毁图表实例
		}
	  },
	  handleNodeClick(params) {
		// this.selectedGraph = params.name.toLowerCase(); // 更新点击的节点名称
		const componentMap = {
		  CPU: "CPU",
		  Memory: "Memory",
		  GPU: "Gpu",
		  Input: "Input",
		  Output: "Output",
		  "GPU %": "GpuRate",
		  "Disk Wr": "DiskWrite",
		  "Disk Rd": "DiskRead",
		};
		this.selectedGraph = componentMap[params.name].toLowerCase();
		if (this.selectedGraph) {
		  // this.selectedGraph = componentName;
		  this.showGraphModal = true;
		}
	  },
	  refreshCharts() {
		console.log("refreshCharts");
		const charts = ["inputChart", "outputChart", "cpuChart", "gpuChart", "gpuRateChart", "memoryChart", "diskReadChart", "diskWriteChart"];
  
		charts.forEach((chartName) => {
		  if (this.$refs[chartName] && this.$refs[chartName].refreshChart) {
			this.$refs[chartName].refreshChart();
		  }
		});
	  },
	  updateChartData() {
		this.myChart.setOption({
		  series: [
			{
			  type: "graph",
			  layout: "none",
			  data: [
				{ name: "通", x: 200, y: 100, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
				{ name: "算", x: 100, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
				{ name: "存", x: 300, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
				{ name: "Input", x: 150, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "Output", x: 250, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "CPU", x: 0, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "GPU", x: 0, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "GPU %", x: 80, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "Memory", x: 400, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "Disk Wr", x: 400, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
				{ name: "Disk Rd", x: 320, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
			  ].map((item) => {
				if (item.name === "CPU") {
				  item.label = { show: true, position: "inside", formatter: `CPU\n${this.cpuData[this.cpuData.length - 1]}m` };
				} else if (item.name === "GPU") {
				  item.label = { show: true, position: "inside", formatter: `GPU\n${this.gpuData[this.gpuData.length - 1]}Mi` };
				} else if (item.name === "Memory") {
				  item.label = { show: true, position: "inside", formatter: `Memory\n${this.memData[this.memData.length - 1]}Mi` };
				} else if (item.name === "Input") {
				  item.label = { show: true, position: "inside", formatter: `Input\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
				} else if (item.name === "Output") {
				  item.label = { show: true, position: "inside", formatter: `Output\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
				} else if (item.name == "GPU %") {
				  item.label = { show: true, position: "inside", formatter: `GPU %\n${this.gpuRate[this.gpuRate.length - 1]}%` };
				} else if (item.name == "Disk Wr") {
				  item.label = { show: true, position: "inside", formatter: `Disk Wr\n${(this.diskWrite[this.diskWrite.length - 1] / 1000).toFixed(2)}kB` };
				} else if (item.name == "Disk Rd") {
				  item.label = { show: true, position: "inside", formatter: `Disk Rd\n${(this.diskRead[this.diskRead.length - 1] / 1000).toFixed(2)}kB` };
				}
				return item;
			  }),
			  links: [
				{ source: "通", target: "算", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "算", target: "存", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "存", target: "通", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "通", target: "Input", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "通", target: "Output", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "算", target: "CPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "算", target: "GPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "算", target: "GPU %", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "存", target: "Memory", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "存", target: "Disk Wr", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
				{ source: "存", target: "Disk Rd", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
			  ],
			  label: {
				show: true,
				position: "inside",
				formatter: "{b}",
				color: "black",
				fontSize: 22,
			  },
			  lineStyle: {
				curveness: 0,
				width: 2,
				color: "white",
				opacity: 1,
			  },
			},
		  ],
		});
	  },
	  showGraph(type) {
		this.selectedGraph = type;
		this.showGraphModal = true;
	  },
	  closeGraph() {
		this.showGraphModal = false;
		this.selectedGraph = null;
		if (this.myChart) {
		  this.myChart.dispose();
		}
		// 重新初始化图表
		this.$nextTick(() => {
		  this.initChart();
		});
	  },
	},
	mounted() {
	  this.$nextTick(() => {
		this.initChart();
		this.initLoadChart();
		this.fetchData();
		this.intervalId = setInterval(this.fetchData, 1000);
		this.showGraphModal = true;
	  });
	},
	beforeUnmount() {
	  if (this.intervalId) {
		clearInterval(this.intervalId);
	  }
	  if (this.myChart) {
		this.myChart.dispose(); // 销毁图表实例
	  }
	  if (this.loadChart) {
		this.loadChart.dispose();
	  }
	  // 关闭 WebSocket 连接
	  if (this.ws) {
		this.ws.close();
	  }
	},
  };
  </script>
  
  <style scoped>
  .container {
	display: grid;
	grid-template-columns: 3fr 2fr;
	/* 左侧2份，右侧1份 */
	width: 100%;
	height: 100%;
  }
  
  .left-side {
	width: 90%;
	height: 100%;
  }
  
  .right-side {
	display: flex;
	flex-direction: column;
	width: 100%;
	height: 100%;
  }
  
  .clean {
	flex: 1;
	height: 80%;
	width: 100%;
  }
  
  .clean img {
	width: 100%;
	height: 80%;
  }
  
  .graph-modal {
	flex: 1;
	height: 100%;
  }
  
  .info-header {
	position: absolute;
	z-index: 1;
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 20px 20px;
	background-color: transparent;
	font-size: 24px;
	font-weight: bold;
	border-radius: 10px;
	max-width: 100%;
	text-shadow: 1px 1px 2px #000;
  }
  
  .name,
  .ip {
	display: inline-block;
	margin: 0 10px;
	font-weight: bolder;
  }
  
  .name {
	color: #4caf50;
  }
  
  .ip {
	color: #4caf50;
  }
  
  .info-header .name::before {
	content: "Name: ";
	font-weight: bold;
  }
  
  .info-header .ip::before {
	content: "IP: ";
	font-weight: bold;
  }
  
  .info-header:hover {
	background-color: #444;
	transition: background-color 0.3s;
	cursor: pointer;
  }
  </style>
  